Skip to content

Release prep 1.0.0: version bump, appcast cleanup, stable-release tagging#923

Merged
malpern merged 1 commit into
masterfrom
claude/release-1.0-prep
Jun 13, 2026
Merged

Release prep 1.0.0: version bump, appcast cleanup, stable-release tagging#923
malpern merged 1 commit into
masterfrom
claude/release-1.0-prep

Conversation

@malpern

@malpern malpern commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Prepares master for the 1.0.0 stable cut. Landing this first means release.sh can run with no version arg, so its in-place CFBundleVersion=<full-string> auto-bump (which Sparkle would mis-compare as older than beta3) never runs, and the v1.0.0 tag captures a tree that already says 1.0.0.

Changes

  • Info.plistCFBundleShortVersionString 1.0.0-beta31.0.0; CFBundleVersion 34. build-and-sign.sh writes <sparkle:version> from CFBundleVersion, so 4 > 3 is what makes existing beta3 users get offered the update.
  • appcast.xml — remove the stale Version 1.0.0 entry (sparkle:version=1, enclosure pointing at a non-existent v1.0.0 release) left over from a prior local run. With 1 < 3 it was a permanently-unofferable broken entry; leaving it would put a bogus 1.0.0 next to the real one.
  • release.sh — mark the GitHub Release --prerelease only for versions with a semver pre-release suffix (e.g. 1.0.0-beta4); stable X.Y.Z now publishes as Latest release. Scalar + ${x:+...} form keeps it safe under set -u on bash 3.2 (macOS).
  • CHANGELOG.md — cut [1.0.0] section from [Unreleased] (security: cmd-feature removal; feature list; known limitations).

Deliberately NOT changed

  • Sources/KeyPathHelper/Info.plist stays at 1.1.0/2. It already drifted from the app before this release; bumping it changes the bundled privileged helper and can trigger a re-approval prompt for existing users on auto-update. Reconciling helper versioning is a clean post-1.0 follow-up.

Verification

  • plutil -lint Info.plist
  • xmllint --noout appcast.xml ✓ (well-formed; only beta3 + the to-be-appended 1.0.0 entry remain)
  • bash -n release.sh ✓ and prerelease logic unit-checked: 1.0.0 → Latest, 1.0.0-beta4 → --prerelease
  • No Swift changes (release-config only), so the Swift review gate is N/A.

Also done out-of-band on this clone

  • Deleted 6 stale local-only tags (v1.0.0v1.0.4, v1.0.4-2) — 2022-era inherited Kanata tags never pushed to KeyPath's origin — so release.sh can create v1.0.0. SHAs recorded; commits stay reachable.

After merge: pull master → release-candidate.sh (signed/notarized QA in /Applications) → smoke → release.sh 1.0.0.

…ging

Prepares master for the 1.0.0 stable cut (run release.sh with no version
arg so its in-place CFBundleVersion=<full-string> auto-bump never runs).

- Info.plist: CFBundleShortVersionString 1.0.0-beta3 → 1.0.0;
  CFBundleVersion 3 → 4 so Sparkle sees 1.0.0 as newer than beta3
  (build-and-sign.sh writes <sparkle:version> from CFBundleVersion).
- appcast.xml: remove the stale "Version 1.0.0" entry (sparkle:version=1,
  pointing at a non-existent v1.0.0 release) left over from a prior local
  run — it would otherwise sit alongside the real 1.0.0 entry as a broken,
  never-offered update.
- release.sh: mark GitHub Release --prerelease only for versions carrying a
  semver pre-release suffix; stable X.Y.Z publishes as "Latest release".
  Scalar + ${x:+...} keeps it safe under set -u on bash 3.2.
- CHANGELOG.md: cut [1.0.0] section from [Unreleased] (security: cmd-feature
  removal; features; known limitations).

Helper Info.plist intentionally untouched: bumping it changes the bundled
privileged helper and can trigger a re-approval prompt on auto-update.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@claude

claude Bot commented Jun 13, 2026

Copy link
Copy Markdown

Review: Release prep 1.0.0

Overall this is a tight, well-scoped release-prep PR. The rationale is clearly documented and the changes are minimal. A few notes below.


✅ What's correct

Info.plist version bumpsCFBundleShortVersionString 1.0.0-beta3 → 1.0.0 and CFBundleVersion 3 → 4 are both correct. Sparkle compares CFBundleVersion (the integer build number) when deciding whether to offer an update, so 4 > 3 ensures existing beta3 users are prompted. Storing it as <string> in the plist is standard.

appcast.xml cleanup — The removed entry had sparkle:version=1, so 1 < 3 (beta3's build number) and it was permanently un-offerable. The enclosure URL pointed at a non-existent release asset. Removing it is correct; leaving it alongside the real 1.0.0 entry would have created a confusing duplicate with a broken download URL.

Pre-release detection logic[[ "$VERSION" == *-* ]] correctly identifies semver pre-release strings (anything with a hyphen). Stable X.Y.Z versions fall through cleanly.

set -u safety — Explicitly initializing PRERELEASE_FLAG="" before the conditional covers the case where the script runs with set -u. The ${PRERELEASE_FLAG:+...} form then safely handles the empty-string case without passing a blank argument to gh.

CHANGELOG — Cutting the 1.0.0 section from Unreleased looks correct. Dropping the internal CI notes ("CI enforces coverage non-regression…") and the release-blocker issue reference is appropriate for a user-facing changelog. The Security section leading the 1.0.0 entry is a good call given the cmd feature removal is a meaningful safety property.


Minor findings

release.sh: slight redundancy in the flag expansion

PRERELEASE_FLAG=""
if [[ "$VERSION" == *-* ]]; then
    PRERELEASE_FLAG="--prerelease"
fi
...
${PRERELEASE_FLAG:+"$PRERELEASE_FLAG"} \

Because the flag string is a constant (--prerelease), the variable reference in the expansion is redundant — the value of PRERELEASE_FLAG is already identical to the string you'd want to substitute. A slightly cleaner form is:

${PRERELEASE_FLAG:+--prerelease} \

No functional difference; just removes one indirection. Not a blocker.

--notes URL is self-referential

--notes "See [release notes](https://github.com/malpern/KeyPath/releases/tag/v${VERSION}) for details."

The body of the GitHub Release links back to the same release page. This is pre-existing behavior (not introduced here), but worth fixing at some point — e.g., linking to the CHANGELOG or a help guide instead.

CHANGELOG missing comparison links

Keep a Changelog convention expects a footer link block like:

[1.0.0]: https://github.com/malpern/KeyPath/compare/v0.0.0-internal...v1.0.0
[0.0.0-internal]: https://github.com/malpern/KeyPath/commits/v0.0.0-internal

These are optional if the repo doesn't use them today, but worth adding at some point for navigability. Not blocking for 1.0.0.

[Unreleased] section — After this PR, the [Unreleased] section is empty. That's correct per Keep a Changelog conventions (empty is the right state between releases), just confirming it's intentional.


No concerns on

  • Helper plist staying at 1.1.0/2 — the reasoning (avoid re-approval prompt on auto-update) is sound, and it's explicitly noted in the PR description.
  • No Swift source changes means the Swift review gate and test suite are not relevant here.
  • The VERSION == *-* check won't false-positive on realistic version strings in this project.

Verdict: Ready to merge. The minor notes above are all post-1.0 cleanup candidates, nothing blocking.

@malpern malpern merged commit d034aa3 into master Jun 13, 2026
5 checks passed
@malpern malpern deleted the claude/release-1.0-prep branch June 13, 2026 14:12
malpern added a commit that referenced this pull request Jun 13, 2026
Burndown now plots actual through Sat (no leftover Thu projection): Sat is
the current marker near the floor; ~3h of execution left (RC + smoke +
publish), not feature work. Verdict reflects release-prep #923 merged
(version → 1.0.0/build 4, appcast + squatting-tag cleanup) with the signed
RC building. Footer timestamp Wed → Sat 2026-06-13; drops the overclaimed
"auto-synced" wording (it's hand-maintained).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
malpern added a commit that referenced this pull request Jun 13, 2026
* Dashboard: Friday morning state — all Thu work merged, today is notes + screenshots

6 of 10 gates closed. Thursday's two Neovim detail-page bugs (#903
wrong component, #908 sheet clipping) are on master. Verdict + schedule
updated to Friday: gates 8 (notes) and 9 (screenshot pass) close today,
~1h total; gate 7 RC + gate 10 video on Sat. Countdown to 1 day.

* Dashboard: fix system category count clobbered by countdown replace

The Fri-AM countdown edit globally replaced <span class=num>2</span>
and accidentally knocked the 'system' category bar from its (already
wrong) 2 down to 1. Real count is 3 (macOS Function Keys, Leader Key,
Fast Navigation); categories now sum to 22 again. Caught by codex +
claude review on #910.

* Dashboard: Saturday release-day state — #899 + #921 merged, cutting the RC

8 of 10 gates closed. Countdown to 0 (TODAY). Verdict → 'Shipping
today': cmd-removal + screenshot cleanup merged after gating two
runner flakes (#922). Gate 7 (RC) now in-progress; gate 9 closed
(screenshots stripped/preserved via #921/#920); gate 8 finalizing
with qualified import framing. Also fixes the system category count
(3, not the review-flagged 1).

* Dashboard: Saturday release-day — burndown, verdict, footer to current

Burndown now plots actual through Sat (no leftover Thu projection): Sat is
the current marker near the floor; ~3h of execution left (RC + smoke +
publish), not feature work. Verdict reflects release-prep #923 merged
(version → 1.0.0/build 4, appcast + squatting-tag cleanup) with the signed
RC building. Footer timestamp Wed → Sat 2026-06-13; drops the overclaimed
"auto-synced" wording (it's hand-maintained).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Dashboard: note overlay picker blocker found + fixed in RC QA (#924)

RC QA surfaced the overlay output-type picker being unclickable; root-caused
to WindowAnchoredPopover's identity-only Equatable discarding content updates,
fixed and reworked into a drill-down with Launch App search (#924). Verdict now
reflects re-cutting the RC from master with the fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant